//
//  RequestOperation.m
//  OCBase
//
//  Created by 侯伟 on 2017/8/10.
//  Copyright © 2017年 侯伟. All rights reserved.
//

#import "RequestOperation.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import "RequestManager.h"
#import "UploadManager.h"
#import "YYModel.h"
#import "AFNetworking.h"
#import "Toast.h"
#import "Sign.h"
#import "RSA.h"
#import "AppConfig.h"
#import "NetworkConfig.h"

@implementation RequestOperation
@dynamic URL;

static NSString*  _URL;

+ (void)setURL:(NSString *)URL{
    _URL = URL;
}


+ (void)setRequestHeader:(NSDictionary *)requestHeader{
    
    [[RequestManager sharedInstance] setRequestHeader:requestHeader];
    
    [[UploadManager sharedInstance] setRequestHeader:requestHeader];
}



#pragma mark - 通用：数据请求（请求数据为model）
+ (void)request:(HRequest *)request quite:(BOOL)quite callBack:(ResponseBlock)callBack{
    
    NSDictionary *parameters = [request params];
    NSString *url = [self allURL:_URL method:[request path]];
    RequestMethod method = [request method];
    Class responseClass = [request responseClass];
    
    RSLOG(@"\n Request:%@->Parameters:%@\n", url, parameters);
    
    if (!url.length){
        return;
    }
    
    if(!quite){
        [Toast spin:NULL inView:[UIViewController topViewController].view];
    }
    
    [[RequestManager sharedInstance] requestWithURL:url method:method params:parameters callback:^(id  _Nullable responseObj, BOOL success) {
        if(!quite){
            [Toast hidden:[UIViewController topViewController].view];
        }
        RSLOG(@"\n Request:%@->Response:%@\n", url, [responseObj yy_modelToJSONString]);
        HResponse* response;
        if(success){
            response = [HResponse yy_modelWithJSON:responseObj];
            if(responseClass){
                if([response.data isKindOfClass:NSArray.class]){
                    response.data = [NSArray yy_modelArrayWithClass:responseClass json:response.data];
                }else{
                    response.data = [responseClass yy_modelWithJSON:response.data];
                }
            }
        }else{
            NSError* error = responseObj;
            response = [HResponse new];
            response.code = error.code;
            response.msg = error.localizedDescription;
        }
        
        //callback
        if(callBack){
            [Queue asyncMain:^{
                callBack(response);
            }];
        }
    }];
}



//
+ (void)encryptedRequest:(HRequest *)request quite:(BOOL)quite callBack:(ResponseBlock)callBack{
    
    NSDictionary *parmas = [request params];
    NSString *url = [self allURL:_URL method:[request path]];
    RequestMethod method = [request method];
    Class responseClass = [request responseClass];
    
    RSLOG(@"\n Request:%@->Parameters:%@\n", url, parmas);
    
    if (!url.length){
        return;
    }
    
    NSString* paramsJson = [parmas yy_modelToJSONString];
    paramsJson = [NSString stringWithFormat:@"%@%@",paramsJson,RSA_OFFSET];
    
    NSString* encrypyStr = [RSA encryptString:paramsJson publicKey:RSA_KEY];
    
    if(!quite){
        [Toast spin:NULL inView:[UIViewController topViewController].view];
    }
    
    [[RequestManager sharedInstance] requestWithURL:url method:method params:@{@"sign":encrypyStr} callback:^(id  _Nullable responseObj, BOOL success) {
        if(!quite){
            [Toast hidden:[UIViewController topViewController].view];
        }
        RSLOG(@"\n Request:%@->Response:%@\n", url, [responseObj yy_modelToJSONString]);
        
        //1.请求成功
        HResponse* response;
        if(success){
            response = [HResponse yy_modelWithJSON:responseObj];
            if(responseClass){
                if([response.data isKindOfClass:NSArray.class]){
                    response.data = [NSArray yy_modelArrayWithClass:responseClass json:response.data];
                }else{
                    response.data = [responseClass yy_modelWithJSON:response.data];
                }
            }
        }else{
            NSError* error = responseObj;
            response = [HResponse new];
            response.code = error.code;
            response.msg = error.localizedDescription;
        }
        if(callBack){
            [Queue asyncMain:^{
                callBack(response);
            }];
        }
    }];
}


/// 通用请求
/// @param url 完整地址
/// @param parmas 参数
/// @param method 方式
/// @param quite quite YES静态加载
/// @param callBack -
+ (void)request:(NSString *)url parmas:(NSDictionary*)parmas method:(RequestMethod)method quite:(BOOL)quite callBack:(RequestResult)callBack{

#ifdef DEBUG
    NSLog(@"\n Request:%@->Parameters:%@\n", url, parmas);
#endif
    
    if(!quite){
        [Toast spin:NULL inView:[UIViewController topViewController].view];
    }
    [[RequestManager sharedInstance] requestWithURL:url method:method params:parmas callback:^(id _Nonnull response,BOOL success) {
        if(!quite){
            [Toast hidden:[UIViewController topViewController].view];
        }
        if(callBack){
            [Queue asyncMain:^{
                callBack(response,success);
            }];
        }
    }];
}

/// 通用加密请求
/// @param url 完整地址
/// @param parmas 参数
/// @param method 方式
/// @param quite quite YES静态加载
/// @param callBack -
+ (void)encryptedRequest:(NSString *)url parmas:(NSDictionary*)parmas method:(RequestMethod)method quite:(BOOL)quite callBack:(RequestResult)callBack{
  
#ifdef DEBUG
    NSLog(@"\n Request:%@->Parameters:%@\n", url, parmas);
#endif

    NSString* paramsJson = [parmas yy_modelToJSONString];
    paramsJson = [NSString stringWithFormat:@"%@%@",paramsJson,RSA_OFFSET];
    
    NSString* encrypyStr = [RSA encryptString:paramsJson publicKey:RSA_KEY];
    
    if(!quite){
        [Toast spin:NULL inView:[UIViewController topViewController].view];
    }
    
    [[RequestManager sharedInstance] requestWithURL:url method:method params:@{@"sign":encrypyStr} callback:^(id _Nonnull response,BOOL success) {
        if(!quite){
            [Toast hidden:[UIViewController topViewController].view];
        }
        if(callBack){
            [Queue asyncMain:^{
                callBack(response,success);
            }];
        }
    }];
}


#pragma mark - 上传文件
+ (void)upload:(HRequest *)request files:(NSArray<UploadFile *> *)files quite:(BOOL)quite callBack:(ResponseBlock)callBack{
    if (files == nil){
        [self request:request quite:quite callBack:callBack];
        return;
    }
    
    NSDictionary *parameters = [request params];
    NSString *url = [self allURL:_URL method:[request path]];
#ifdef DEBUG
    NSLog(@"\n Request:%@->Parameters:%@\n", url, parameters);
#endif
    if (!url.length){
        if (callBack){
            HResponse* response = [HResponse new];
            response.msg = @"网络请求地址配置错误";
            response.code = -1;
            response.data = nil;
            callBack(response);
        }
        return;
    }
    
    Class responseClass = [request responseClass];
    
    if(!quite){
        [Toast spin:@"上传中..." inView:[UIViewController topViewController].view];
    }
    
    [[UploadManager sharedInstance] upload:url params:parameters fileConfigs:files callback:^(id  _Nullable responseObj, BOOL success) {
        
        if(!quite){
            [Toast hidden:[UIViewController topViewController].view];
        }
        //1.成功
        if(success){
            HResponse* response = [HResponse yy_modelWithJSON:responseObj];
            if(responseClass){
                if([response.data isKindOfClass:NSArray.class]){
                    response.data = [NSArray yy_modelArrayWithClass:responseClass json:response.data];
                }else{
                    response.data = [responseClass yy_modelWithJSON:response.data];
                }
            }
            
            //1.1 接口请求成功直接返回结果
            if(callBack){
                [Queue asyncMain:^{
                    callBack(response);
                }];
            }
        }else{
            //2.失败
            NSError* error = responseObj;
            HResponse* response = [HResponse new];
            response.code = error.code;
            response.msg = error.localizedDescription;
            response.data = nil;
            if(callBack){
                [Queue asyncMain:^{
                    callBack(response);
                }];
            }
        }
    }];
}


#pragma mark --private

+ (NSString *)allURL:(NSString *)baseURL method:(NSString *)method{
    if (!baseURL.length && !method.length){
        return @"";
    }
    
    if([method hasPrefix:@"http"] || [method hasPrefix:@"https"] || [method hasPrefix:@"www"])
        return method;
    
    NSString *urlString = [NSString stringWithFormat:@"%@/%@",baseURL,method];
    
    return urlString;
}

#pragma mark - 监听网络状态
+ (void)startMonitoringWithResult:(void(^)(BOOL available))block{
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        
        BOOL available = YES;
        switch (status){
            case AFNetworkReachabilityStatusReachableViaWWAN:
            case AFNetworkReachabilityStatusReachableViaWiFi:
                available = YES;
                break;
            default:
                available = NO;
                break;
        }
        if(block){
            block(available);
        }
    }];
    
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}

+ (void)stopMonitoring{
    [[AFNetworkReachabilityManager sharedManager] stopMonitoring];
}

@end
